package com.hang.gymmanager.service.impl;

import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hang.gymmanager.Enum.ImgTypeEnum;
import com.hang.gymmanager.Enum.OrderStatusEnum;
import com.hang.gymmanager.Enum.OrderTypeEnum;
import com.hang.gymmanager.convert.PojoConvert;
import com.hang.gymmanager.entity.*;
import com.hang.gymmanager.exception.BusinessException;
import com.hang.gymmanager.mapper.CommodityMapper;
import com.hang.gymmanager.mapper.OrderMapper;
import com.hang.gymmanager.mapper.WalletMapper;
import com.hang.gymmanager.req.*;
import com.hang.gymmanager.res.CommodityRes;
import com.hang.gymmanager.res.UserCommodityPageRes;
import com.hang.gymmanager.service.CommodityService;
import com.hang.gymmanager.service.OrderService;
import com.hang.gymmanager.service.UserInfoService;
import com.hang.gymmanager.util.SecurityUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.javassist.bytecode.ParameterAnnotationsAttribute;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.math.BigDecimal;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.util.List;

import static com.hang.gymmanager.Enum.CommonConstant.LINUX_PATH;

@Service
@Slf4j
@RequiredArgsConstructor
public class CommodityServiceImpl extends ServiceImpl<CommodityMapper, CommodityEntity> implements CommodityService {

    private final CommodityMapper commodityMapper;
    private final PojoConvert convert;

    private final UserInfoService userInfoService;
    private final WalletMapper walletMapper;
    private final OrderMapper orderMapper;

    @Override
    public Page<CommodityRes> getAllCommodity(PageCommodityReq req) {
        Page page = new Page<>(req.getPageNum(),req.getPageSize());
        Page<CommodityRes> commodityPage = commodityMapper.getCommodityPage(req, page);
        return commodityPage;
    }

    @Override
    public Integer addCommodity(AddCommodityReq req) {
        CommodityEntity commodityEntity = convert.addCommodityReq2Entity(req);
        this.getBaseMapper().insert(commodityEntity);
        return commodityEntity.getId();
    }

    @Override
    public void deleteCommodity(DeleteCommodityReq req) {
        UpdateWrapper<CommodityEntity> wrapper = new UpdateWrapper<>();
        wrapper.lambda().eq(CommodityEntity::getId,req.getId());
        int delete = this.getBaseMapper().delete(wrapper);
        if(delete!=1){
            throw new BusinessException("删除商品失败，请重试");
        }

    }

    @Override
    public void updateCommodity(UpdateCommodityReq req) {
        CommodityEntity entity = new CommodityEntity();
        entity.setId(req.getId());
        if(req.getInventory()!=null){
            entity.setInventory(req.getInventory());
        }
        if(!ObjectUtil.isNull(req.getPrice())){
            entity.setPrice(req.getPrice());
        }
        if(!ObjectUtil.isNull(req.getCommodityName())){
            entity.setCommodityName(req.getCommodityName());
        }
        if(req.getCommodityType()!=null){
            entity.setCommodityType(req.getCommodityType());
        }
        this.getBaseMapper().updateById(entity);
    }

    @Override
    public CommodityEntity commodityDetail(Integer id) {
        QueryWrapper<CommodityEntity> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(CommodityEntity::getId,id);
        CommodityEntity entity = this.getBaseMapper().selectOne(wrapper);
        if(ObjectUtil.isNull(entity)){
           throw new BusinessException("该商品不存在，请重试");
        }
        return entity;
    }

    @Override
    public Page<UserCommodityPageRes> userCommodityPage(userCommodityPageReq req) {
        Page queryPage = new Page(req.getPageNum(),req.getPageSize());
        QueryWrapper<CommodityEntity> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(CommodityEntity::getCommodityType,req.getType())
                .orderByAsc(CommodityEntity::getId);
        Page result = this.getBaseMapper().selectPage(queryPage, wrapper);
        List<UserCommodityPageRes> res = convert.userCommodityPageEntity2Res(result.getRecords());
        result.setRecords(res);
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public synchronized void buy(List<BuyCommodityReq> req) {
        LocalDateTime create = LocalDateTime.now();
        //获取用户id
        Integer userId = SecurityUtils.getUserId();
        UserInfoEntity userInfoEntity = userInfoService.getBaseMapper().selectById(userId);
        //计算总价
        final BigDecimal[] totalMount = {new BigDecimal(0)};
        req.stream().forEach(e->{
            CommodityEntity temp = this.getBaseMapper().selectById(e.getId());
            totalMount[0] = totalMount[0].add(temp.getPrice().multiply(new BigDecimal(e.getCount())));
        });
        WalletEntity wallet = walletMapper.selectById(userId);
        if(wallet.getBalance().doubleValue()< totalMount[0].doubleValue()){
            throw new BusinessException("账户余额不足");
        }
        //减去库存
        req.stream().forEach(e->{
            CommodityEntity temp = this.getBaseMapper().selectById(e.getId());
            if(temp.getInventory()<e.getCount()){
                throw new BusinessException("商品"+temp.getCommodityName()+"库存不足,请重试");
            }else {
                temp.setInventory(temp.getInventory()-e.getCount());
                this.saveOrUpdate(temp);
            }
        });
        //扣款
        wallet.setBalance(wallet.getBalance().subtract(totalMount[0]));
        walletMapper.updateById(wallet);
        //插入订单
        StringBuffer buffer = new StringBuffer("购买了商品:");
        req.stream().forEach(e->{
            CommodityEntity temp = this.getBaseMapper().selectById(e.getId());
            buffer.append(e.getCount()+"件商品:"+temp.getCommodityName()+",");
        });
        OrderEntity order = new OrderEntity();
        Snowflake snowflake = new Snowflake();
        order.setOrderId(snowflake.nextId())
                .setUserId(userId)
                .setUserName(userInfoEntity.getName())
                .setType(OrderTypeEnum.COMMODITY.getValue())
                .setStatus(OrderStatusEnum.PAYED.getValue())
                .setCreateTime(create)
                .setFinishTime(LocalDateTime.now())
                .setRelationId(null)
                .setPrice(totalMount[0])
                .setMessage(buffer.deleteCharAt(buffer.length()-1).toString());
        orderMapper.insert(order);
    }

    @Override
    public void uploadPic(MultipartFile file, Integer commodityId) {
        //如果文件为空 报错
        if (file.isEmpty()) {
            throw new BusinessException("文件为空");
        }
        try {
            //获取项目当前路径
//            String url = "D:\\ideaProject";
            String url = LINUX_PATH;
            Path imgPath = Paths.get(url,"img");
            //获取文件字节流文件
            byte[] bytes = file.getBytes();
            //文件id
            String fileName = ImgTypeEnum.COMMODITY.getValue()+"-"+commodityId+".jpg";
            // 构建保存文件的路径
            Path filePath = imgPath.resolve(fileName);
            // 将文件保存到本地
            Files.write(filePath, bytes);
            //更新数据库记录
            CommodityEntity entity = this.getBaseMapper().selectById(commodityId);
            entity.setImgPath(fileName);
            this.saveOrUpdate(entity);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
